import { getSummary } from '@/services/zhirong/visualAnalysis';
import ProCard from '@ant-design/pro-card';
import Graphin, { Behaviors } from '@antv/graphin';
import { Algorithm, Util } from '@antv/g6';
import { useRequest } from '@umijs/hooks';
import { Select } from 'antd';
import { useContext, useEffect, useState } from 'react';
import CustomMenu from './CustomMenu';
import { colorSets, clusterColorMap } from './color';
import { ContextMenu } from '@antv/graphin-components';
import iconLoader from '@antv/graphin-icons';
import '@antv/graphin-icons/dist/index.css';
import { OptionToolbarTwo } from '@/components/Toolbar';
import VisualAnalysisLayout, { VisualAnalysisContext } from '../VisualAnalysisLayout ';

const { fontFamily } = iconLoader();
const icons = Graphin.registerFontFamily(iconLoader);
const defaultLayout = {
  type: 'graphin-force',
  preset: {
    type: 'concentric',
  },
  animation: true,
  defSpringLen: (_edge, source, target) => {
    /** 默认返回的是 200 的弹簧长度 */
    /** 如果你要想要产生聚类的效果，可以考虑 根据边两边节点的度数来动态设置边的初始化长度：度数越小，则边越短 */
    const nodeSize = 30;
    const Sdegree = source.data.layout.degree;
    const Tdegree = target.data.layout.degree;
    const minDegree = Math.min(Sdegree, Tdegree);
    return minDegree < 3 ? nodeSize * 5 : minDegree * nodeSize;
  },
};

const { ZoomCanvas } = Behaviors;
const { louvain } = Algorithm;
const { uniqueId } = Util;

const nodeMap = {};
const aggregatedNodeMap = {};
const nodeSize = 40;
const badgeSize = 12;

/** 转化函数 */
const transClusterData = (data, sourceData) => {
  const nodes = data.clusters.map((node, index) => {
    const primaryColor = colorSets[index % 11].mainFill;
    clusterColorMap.set(node.id, primaryColor);

    const clusterNode = {
      ...node,
      type: 'graphin-circle',
      style: {
        keyshape: {
          fill: primaryColor,
          fillOpacity: 0.1,
          strokeWidth: 1.2,
          stroke: primaryColor,
          size: nodeSize,
        },
        label: {
          value: `cluster-${node.id}(${node.nodes.length})`,
          fill: '#000',
          fillOpacity: 0.85,
        },
        halo: {
          fill: primaryColor, // '#fff',
          stroke: primaryColor,
          fillOpacity: 0.1,
          strokeWidth: 1.2,
        },
        icon: {
          fontFamily,
          type: 'font',
          value: icons.team,
          fill: primaryColor,
          size: nodeSize / 1.6,
        },
        badges: [
          {
            position: 'RT',
            type: 'text',
            value: node.nodes.length,
            size: [badgeSize, badgeSize],
            fill: primaryColor,
            stroke: primaryColor,
            color: '#fff',
            fontSize: badgeSize * 0.8,
            padding: 0,
            offset: [0, 0],
          },
        ],
      },
    };

    aggregatedNodeMap[node.id] = clusterNode;
    return clusterNode;
  });

  const edges = data.clusterEdges.map((edge) => {
    const size = Math.log(edge.count) || 0.5;
    const id = `edge-${uniqueId()}`;
    return {
      ...edge,
      id,
      style: {
        keyshape: {
          size: size > 0.5 ? size : 0.5,
          stroke: '#AAB7C4',
        },
      },
    };
  });
  sourceData.nodes?.forEach((node) => {
    nodeMap[node.id] = node;
  });
  console.log(nodeMap);
  return {
    nodes,
    edges,
  };
};
let refreshData;

const SummaryGraph = () => {
  const [search, setSearch] = useState({ eid: 'fa65c5e6-c5e9-11e7-a96b-00163e1254b5' });
  const [state, setState] = useState({
    data: {},
    source: {},
    clusteredData: {},
    visible: false,
    layout: { ...defaultLayout, animation: true },
  });
  const [loading, setLoading] = useState(false);
  const refresh = () => {
    setLoading(true);
    setTimeout(() => setLoading(false), 0);
  };
  const { run, loading: loadingGraph } = useRequest(getSummary, {
    onSuccess: (res) => {
      const { nodes, links } = res.data;
      const edges = [];
      const ids = nodes.map((node) => node.id);
      links.forEach((link) => {
        if (ids.indexOf(link.source) !== -1 && ids.indexOf(link.target) !== -1) {
          edges.push(link);
        }
      });
      const clusteredData = louvain({ nodes, edges });
      const data = transClusterData(clusteredData, { nodes, edges });
      refreshData = data;
      setState((preState) => {
        return {
          ...preState,
          data,
          source: res,
          clusteredData,
        };
      });
    },
  });
  useEffect(() => {
    run({
      entityA: search.eid,
    });
  }, [search, run]);

  const { data } = state;
  return (
    <VisualAnalysisLayout title="公司社区发现" onSubmit={setSearch}>
      <ProCard loading={loading || loadingGraph} gutter={8} style={{
        borderRadius: '8px',
      }}>
        <ProCard colSpan={24}>
          <Graphin data={data} layout={defaultLayout} fitview>
            <ZoomCanvas />
            <ContextMenu>
              <CustomMenu
                state={state}
                updateState={setState}
                nodeMap={nodeMap}
                aggregatedNodeMap={aggregatedNodeMap}
              />
            </ContextMenu>
            <OptionToolbarTwo direction={'horizontal'} refresh={refresh} />
          </Graphin>
        </ProCard>
      </ProCard>
    </VisualAnalysisLayout>
  );
};

export default SummaryGraph;
